home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 1 / CU Amiga Magazine CD-ROM Special Edition (1995)(EMAP Images)(GB)[Issue 1995-11].iso / Aminet / comm / tcp / AmiTCPsdk_40.lha / AmiTCP-4.0 / src / netlib / _chkufb.c < prev    next >
C/C++ Source or Header  |  1994-09-29  |  3KB  |  149 lines

  1. RCS_ID_C="$Id: _chkufb.c,v 4.1 1994/09/29 23:09:02 jraja Exp $";
  2. /*
  3.  *      _chkufb.c - return struct ufb * from a file handle (SAS/C)
  4.  *
  5.  *      Copyright © 1994 AmiTCP/IP Group, 
  6.  *                       Network Solutions Development Inc.
  7.  *                       All rights reserved.
  8.  */
  9.  
  10. #include <ios1.h>
  11. #include <stdlib.h>
  12. #include <errno.h>
  13. #include <bsdsocket.h>
  14. #include <sys/cdefs.h>
  15. #include <amitcp/socketbasetags.h>
  16. #include <syslog.h>
  17.  
  18. extern unsigned long __fmask;
  19. extern int (*__closefunc)(int);
  20.  
  21. long ASM fdCallback(REG(d0) int fd, REG(d1) int action);
  22.  
  23. /*
  24.  * The initializator priority is just above the standard I/O, so that this
  25.  * will be called after the standard I/O is initialized
  26.  */
  27. long __stdargs
  28. _STI_510_install_AmiTCP_callback(void)
  29. {
  30.   if (SocketBaseTags(SBTM_SETVAL(SBTC_FDCALLBACK), &fdCallback, TAG_END)) {
  31.     syslog(LOG_ERR, "Cannot install fdCallback!");
  32. #if __VERSION__ > 6 || __REVISION__ > 3
  33.     return 1;
  34. #else
  35.     exit(20);
  36. #endif
  37.   }
  38.  
  39.   /*
  40.    * Set up __closefunc (which is used at stdio cleanup)
  41.    */
  42.   __closefunc = __close;
  43.  
  44.   /*
  45.    * Set default file mask to UNIX style
  46.    */
  47.   __fmask = 0644; 
  48.  
  49.   return 0;
  50. }
  51.  
  52. long ASM SAVEDS
  53. fdCallback(REG(d0) int fd, REG(d1) int action)
  54. {
  55.   struct UFB *ufb;
  56.   int fd2;
  57.  
  58. #ifdef DEBUG
  59.   syslog(LOG_INFO, "fdCallback(fd: %d, action: %d)", fd, action);
  60. #endif
  61.  
  62.   switch (action) {
  63.   case FDCB_FREE:
  64.     ufb = __chkufb(fd);
  65.     if (ufb == NULL)
  66.       return EBADF;
  67.  
  68.     if (!(ufb->ufbflg & UFB_SOCK) && ufb->ufbflg != 0) {
  69. #ifdef DEBUG
  70.       syslog(LOG_ERR, "fdCallback: fd (%d) is not a socket!", fd);
  71. #endif
  72.       return ENOTSOCK;
  73.     }
  74.  
  75.     ufb->ufbflg = 0;
  76.     return 0;
  77.  
  78.   case FDCB_ALLOC:
  79.     do {
  80.       ufb = __allocufb(&fd2);
  81.       if (ufb == NULL)
  82.     return ENOMEM;
  83. #ifdef DEBUG
  84.       if (fd2 > fd) {
  85.     syslog(LOG_ERR, "fdCallback: fd2(%d) > fd(%d)!", fd2, fd);
  86.     return EINVAL;
  87.       }
  88. #endif
  89.       ufb->ufbflg = UFB_SOCK | UFB_WA | UFB_RA; /* read/write socket */
  90.       ufb->ufbfh = NULL; /* no file handle */
  91.       ufb->ufbfn = NULL; /* no name */
  92.     } while (fd2 < fd);
  93.     return 0;
  94.  
  95.   case FDCB_CHECK:
  96.     ufb = __chkufb(fd);
  97.     if (ufb != NULL && ufb->ufbflg != 0) 
  98.       return EBADF;
  99.     
  100.     return 0;
  101.  
  102.   default:
  103. #ifdef DEBUG
  104.     syslog(LOG_ERR, "fdCallback: invalid action.");
  105. #endif
  106.     return EINVAL;
  107.   }
  108. }
  109.  
  110.  
  111. struct UFB *
  112. __chkufb(int fd)
  113. {
  114.   struct UFB *ufb;
  115.  
  116.   /* a single element cache */
  117.   static struct UFB *last_ufb = NULL;
  118.   static int         last_fd = -1;
  119.  
  120.   _OSERR = 0;
  121.  
  122.   if ((unsigned int)fd >= __nufbs) { /* unsigned cast checks for (fd < 0) */
  123.     errno = EBADF;
  124.     return NULL;
  125.   }
  126.  
  127.   /*
  128.    * Check the cache first
  129.    */
  130.   if (fd == last_fd)
  131.     return last_ufb;
  132.  
  133.   last_fd = fd; /* update cache */
  134.   ufb = __ufbs;
  135.   while (fd > 0 && ufb != NULL) {
  136.     fd--;
  137.     ufb = ufb->ufbnxt;
  138.   }
  139.   last_ufb = ufb; /* update cache */
  140.   
  141.   if (ufb == NULL) {
  142.     last_fd = -1; /* invalidate cache */
  143.     errno = EIO;
  144.     return NULL;
  145.   }
  146.   else
  147.     return ufb;
  148. }
  149.